
enum NetworkError: Error {
    case invalidURL
    case noData
    case decodingError(Error)
    case networkError(Error)
    case serverError(Int) // 处理服务器返回的错误代码 如 200 400 500
    case apiError(APIError) // 处理API返回的错误
    case unknownError(String) // 处理其他未知错误
}

struct APIError: LocalizedError {
    let code: Int
    let message: String

    var errorDescription: String? {
        message
    }
}

class NetworkManager {
    static let shared = NetworkManager()
    private init() {}

    private let baseURL = URL(string: EnvironmentConfig.shared.current.URL_MAIN)!

    private var middlewares: [RequestMiddleware] = [EncryptionMiddleware(), LoggingMiddleware()]

    func send<T: API>(
        _ api: T,
        completion: @escaping (Result<APIResponse<T.Response>, Error>) -> Void
    ) {
        // 首先要对api.path 中的 路径部分进行解析并替换
        //   let path = "/client-product/network/getProductListById/{id}/abc/{abc}/cdf/agc/ddd"
       //    let params: [String: String] = [
       //        "id": "12345",
       //        "abc": "xyz"
       //    ]
       //
       //    // 替换路径中的参数
       //    let replacedPath = replacePathParams(path: path, params: params)
       //    print(replacedPath)  // 输出: /client-product/network/getProductListById/12345/abc/xyz/cdf/agc/ddd
        
        let path = replacePathParams(path: api.path, params: api.pathValues ?? [:])
        var url = baseURL.appendingPathComponent(path)
        if let value = URL.init(string: path), path.isURL {
            url = value
        }
        
        var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
        if let query = api.query {
            components?.queryItems = query.map { URLQueryItem(name: $0.key, value: $0.value) }
        }

        guard let url = components?.url else {
            completion(.failure(NetworkError.invalidURL))
            return
        }
        
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = api.method.rawValue.uppercased()

        let defaultHeaders = defaultHeaders()
        for (key, value) in defaultHeaders {
            urlRequest.setValue(value, forHTTPHeaderField: key)
        }
        
        for (k, v) in api.headers {
            urlRequest.setValue(v, forHTTPHeaderField: k)
        }
        
       
        var modifiedAPI = api
        if !(T.RequestBody.self is EmptyBody.Type), let body = api.body {
            do {
                var jsonData = try JSONEncoder().encode(body)
                // 使用中间件来处理请求体
                for middleware in middlewares {
                     (jsonData, modifiedAPI) = try middleware.handleRequest(modifiedAPI, body: jsonData)
                 }
                
                 for (key, value) in modifiedAPI.headers {
                     urlRequest.setValue(value, forHTTPHeaderField: key)
                 }
               
                urlRequest.httpBody = jsonData
                
                if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
//                    let value = api.requiresEncryption ? "text/plain" : "application/json"
                    urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
                }
                
            } catch {
                completion(.failure(error))
                return
            }
        }
        Logger.log(.debug, message: "=====开始请求\(String(describing: urlRequest.url?.absoluteString))===========", tag: .netWork)
        let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
            if let error = error {
                completion(.failure(NetworkError.networkError(error)))
                return
            }

            guard let data = data else {
                completion(.failure(NetworkError.noData))
                return
            }

            if let httpResponse = response as? HTTPURLResponse {
                   switch httpResponse.statusCode {
                   case 200..<300:
                       // 成功的请求，继续处理响应数据
                       break
                   case 400..<500:
                       completion(.failure(NetworkError.serverError(httpResponse.statusCode)))
                       return
                   case 500..<600:
                       completion(.failure(NetworkError.serverError(httpResponse.statusCode)))
                       return
                   default:
                       completion(.failure(NetworkError.unknownError("未知错误")))
                       return
                   }
               }
            
            // 处理响应体
              var finalData = data
              for middleware in self.middlewares {
                  finalData = middleware.handleResponse(modifiedAPI, data: finalData, error: error)
              }
                do {
                    let str = String(data: finalData, encoding: .utf8)
                    print("AAAAAAAAA \(str)")
                    let decodedResponse = try JSONDecoder().decode(APIResponse<T.Response>.self, from: finalData)
                    if decodedResponse.code as? Int != 200 && decodedResponse.code as? String != "ok"
                    {
                        var error: APIError!
                        if let errorCode = decodedResponse.code as? Int {
                           error = APIError(code: errorCode, message: decodedResponse.msg ?? "")
                        }
                        else {
                           error = APIError(code: -1, message: decodedResponse.msg ?? "")
                        }
                        completion(.failure(NetworkError.apiError(error)))
                        return
                    }
                    completion(.success(decodedResponse))
                } catch {
                    completion(.failure(NetworkError.decodingError(error)))
                    Logger.log(.error, message: error.localizedDescription, tag: .netWork)
                }
                
            }
            Logger.log(.debug, message: "===========================结束请求==============================", tag: .netWork)

        task.resume()
    }
    
    
    private func defaultHeaders() -> [String: String]
    {
        let systemName = UIDevice.current.systemName
        let systemVersion = UIDevice.current.systemVersion
        let deviceModelName = UIDevice.currentDevice()
        
        let headers = [
            "X-Mobile-Brand": "APPLE",
            "X-Mobile-Type": deviceModelName,
            "X-OS-Name": systemName,
            "X-OS-Ver": systemVersion,
            "X-App-Ver": getAppVersion(),
            "timestamp": Date().milliStamp,
            "clientId": APP_CLIENTID,
            "Authorization": "Bearer " + (AuthManager.shared.getToken() ?? "")
        ]
        return headers
    }
    
    func replacePathParams(path: String, params: [String: String]) -> String {
        // 正则表达式，匹配路径中的大括号
        let regex = try! NSRegularExpression(pattern: "\\{(.*?)\\}", options: [])
        let nsString = path as NSString
        var result = path
        
        // 匹配所有大括号中的内容
        regex.enumerateMatches(in: path, options: [], range: NSRange(location: 0, length: nsString.length)) { match, _, _ in
            if let match = match {
                let paramName = nsString.substring(with: match.range(at: 1))  // 提取大括号中的参数名
                if let paramValue = params[paramName] {  // 查找字典中是否有对应的值
                    result = result.replacingOccurrences(of: "{\(paramName)}", with: paramValue)
                }
            }
        }
        
        return result
    }

}








